/**
 * Created by pefish on 2017/6/17.
 */
import crypto from 'crypto'
import HttpRequestHelper from './HttpRequestHelper'

export default class DataProvider {
  constructor (apiKey, secretKey) {
    this._httpRequstHelper = new HttpRequestHelper()
    this._symbol = 'ltc_cny' // btc_cny: 比特币 ltc_cny: 莱特币 eth_cny :以太坊
    this._apiKey = apiKey
    this._secretKey = secretKey
  }

  _sign (params) {
    let str = ''
    const keys = Object.keys(params)
    keys.sort()
    for (let key of keys) {
      str = str + key + '=' + params[key] + '&'
    }
    str = str.substr(0, str.length - 1) + `&secret_key=${this._secretKey}`
    str = crypto.createHash('md5').update(str).digest('hex').toUpperCase()
    return str
  }

  /**
   * 获取账户信息
   * @returns {Promise.<*>}
   asset:账户资产，包含净资产及总资产
   borrow:账户借款信息(只有在账户有借款信息时才会返回)
   free:账户余额
   freezed:账户冻结余额
   union_fund:账户理财信息(只有在账户有理财信息时才返回)
   * @private
   */
  async getAccountInfo () {
    const params = {
      'api_key': this._apiKey
    }
    return this._post('https://www.okcoin.cn/api/v1/userinfo.do', params)
  }

  async getDepth () {
    return await this._httpRequstHelper.getJson('https://www.okcoin.cn/api/v1/depth.do?symbol=ltc_cny', {
      'Content-Type': 'application/x-www-form-urlencoded'
    })
  }

  async getTicker () {
    return await this._httpRequstHelper.getJson('https://www.okcoin.cn/api/v1/ticker.do?symbol=ltc_cny', {
      'Content-Type': 'application/x-www-form-urlencoded'
    })
  }

  async getTrades () {
    return await this._httpRequstHelper.getJson('https://www.okcoin.cn/api/v1/trades.do?symbol=ltc_cny', {
      'Content-Type': 'application/x-www-form-urlencoded'
    })
  }

  async getKline () {
    return await this._httpRequstHelper.getJson('https://www.okcoin.cn/api/v1/kline.do', {
      'Content-Type': 'application/x-www-form-urlencoded'
    })
  }

  /**
   * 下单
   * @param type 买卖类型： 限价单（buy/sell） 市价单（buy_market/sell_market）
   * @param price 下单价格 [限价买单(必填)： 大于等于0，小于等于1000000 | 市价买单(必填)： BTC :最少买入0.01个BTC 的金额(金额>0.01*卖一价) / LTC :最少买入0.1个LTC 的金额(金额>0.1*卖一价)] / ETH :最少买入0.01个ETH 的金额(金额>0.01*卖一价)] 市价卖单不传price
   * @param amount 交易数量 [限价卖单（必填）：BTC 数量大于等于0.01 / LTC 数量大于等于0.1 / ETH 数量大于等于0.01 | 市价卖单（必填）： BTC :最少卖出数量大于等于0.01 / LTC :最少卖出数量大于等于0.1 / ETH :最少卖出数量大于等于0.01] 市价买单不传amount
   * @returns {Promise.<void>}
   result:true代表成功返回
   order_id:订单ID
   * @private
   */
  async trade (type, price, amount) {
    const params = {
      'symbol': this._symbol,
      'type': type,
      'price': price,
      'amount': amount
    }
    return this._post('https://www.okcoin.cn/api/v1/trade.do', params)
  }

  /**
   *
   * @param sinceTradeId
   * @returns {Promise.<*>}
   * @private
   date:交易时间
   date_ms:交易时间(ms)
   price: 交易价格
   amount: 交易数量
   tid: 交易生成ID
   type: buy/sell
   */
  async getMyTradeHis (sinceTradeId) {
    const params = {
      'symbol': this._symbol,
      'since': sinceTradeId
    }
    return this._post('https://www.okcoin.cn/api/v1/trade_history.do', params)
  }

  async cancelOrder (orderId) {
    const params = {
      'symbol': this._symbol,
      'order_id': orderId
    }
    return this._post('https://www.okcoin.cn/api/v1/cancel_order.do', params)
  }

  async getOrderInfo (orderId) {
    const params = {
      'symbol': this._symbol,
      'order_id': orderId
    }
    return this._post('https://www.okcoin.cn/api/v1/order_info.do', params)
  }

  /**
   *
   * @param status 查询状态 0：未完成的订单 1：已经完成的订单 （最近两天的数据）
   * @param currentPage 当前页数
   * @param pageLength 每页数据条数，最多不超过200
   * @returns {Promise.<*>}
   * @private
   */
  async getOrderHis (status, currentPage, pageLength) {
    const params = {
      'symbol': this._symbol,
      'status': status,
      'current_page': currentPage,
      'page_length': pageLength
    }
    return this._post('https://www.okcoin.cn/api/v1/order_history.do', params)
  }

  /**
   * 提现
   * @param chargefee 网络手续费 >=0,BTC默认范围 [0.0001，0.01],LTC默认范围 [0.001，0.2],ETH默认范围 [0.01],手续费越高，网络确认越快，OKCoin内部提币设置0
   * @param tradePwd 交易密码
   * @param withdrawAddress 认证的地址、邮箱 或手机号码
   * @param withdrawAmount 提币数量 BTC>=0.01 LTC>=0.1 ETH>=0.01
   * @param target 地址类型 国内站："okcn" 国际站："okcom" OKEX："okex" 外部地址："address"
   * @returns {Promise.<*>}
   * @private
   */
  async withdraw (chargefee, tradePwd, withdrawAddress, withdrawAmount, target) {
    const params = {
      'symbol': this._symbol,
      'status': status,
      'chargefee': chargefee,
      'trade_pwd': tradePwd,
      'withdraw_address': withdrawAddress,
      'withdraw_amount': withdrawAmount,
      'target': target
    }
    return this._post('https://www.okcoin.cn/api/v1/withdraw.do', params)
  }

  async _post (url, params) {
    params['api_key'] = this._apiKey
    const data = await this._httpRequstHelper.post(url, {
      'Content-Type': 'application/x-www-form-urlencoded'
    }, {
      ...params,
      'sign': this._sign(params)
    })
    return data['data']
  }

  async cancelWithdraw (withdrawId) {
    const params = {
      'symbol': this._symbol,
      'withdraw_id': withdrawId
    }
    return this._post('https://www.okcoin.cn/api/v1/cancel_withdraw.do', params)
  }

  async getWithdrawInfo (withdrawId) {
    const params = {
      'symbol': this._symbol,
      'withdraw_id': withdrawId
    }
    return this._post('https://www.okcoin.cn/api/v1/withdraw_info.do', params)
  }
}
